<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>CheckBox Tree Table Of Content</title>

    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/esri/css/esri.css">
    <link rel="stylesheet" href="../../themes/tundra/tundra.css">
    <link rel="stylesheet" href="../../icons/maki.css">

    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; }
      .shadow {
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      #map{ margin: 0; padding: 0; }
      #feedback {
        background: #fff;
        color: #444;
        font-family: arial;
        height: 310px;
        left: 30px;
        margin: 5px;
        padding: 10px;
        position: absolute;
        top: 30px;
        width: 310px;
        z-index: 40;
      }
      #note, #hint { font-size: 80%; }
      #note { font-weight: 700; padding: 0 0 10px 0; }
      #layerList {
        width: 300px;
      }
    </style>

    <script type="text/javascript">
      var dojoConfig = {
            parseOnLoad: true,
            packages: [
              { name: "cbtree",location: "/../../../" }
            ]
      };
    </script>

    <!-- Load the esri ArcGIS API 3.3 for JavaScript -->
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/"></script>
    <script type="text/javascript">
      require(["dojo/aspect",                    // aspect.after()
               "dojo/ready",                    // ready()
               "dijit/tree/dndSource",
               "esri/dijit/Popup",
               "cbtree/Tree",
               "cbtree/extensions/TreeStyling",
               "cbtree/model/ForestStoreModel",
               "cbtree/store/ObjectStore",
							 "dijit/layout/BorderContainer", 
               "dijit/layout/ContentPane",
               "dijit/form/Button",
               "esri/map"
              ], function (aspect, ready, dndSource, Popup, Tree, TreeStyling, 
                            ForestStoreModel, ObjectStore) {

      var map, store, model, tree;

      function on (target, event, listener) {
        // Mimic dojo/on for non-emitters like esri.layers
        var method = "on" + event.replace(/^[a-z]/, function(c) { return c.toUpperCase(); });
        aspect.after( target, method, listener, true );
      }

      function buildTOC (location) {
        var index = [  { id:"layers", tocName:"Layers", icon:"layers", type:"TOC" }  ];

        store = new ObjectStore({data: index});
        model = new ForestStoreModel( { store: store, 
                                        labelAttr:"tocName",
                                        checkedAttr:"defaultVisibility",
                                        query:{"type":"TOC"} 
                                      });
        // Create the checkbox tree adding DnD support and value to icon mapping.
        tree  = new Tree( { model: model, 
                            dndController: dndSource,
                            betweenThreshold: 5,
                            valueToIconMap: { "icon": {"*":"* maki"} },
                            autoExpand: true,
                            showRoot:false
                           },
                           location);
        tree.startup();
      }

      function layerClicked (item, treeNode, event ) {
        // A checkbox was clicked, get all layers from the store whose checked
        // state is 'true' and update layer visibility.
        var layers   = store.query( {"type":"layerInfo", defaultVisibility:true} );
        var layerIds = layers.map( function(layer) {
          return layer.id; 
        });
        map.getLayer("usa").setVisibleLayers(layerIds.length ? layerIds : [-1]);
      }

      function storeLayers(layerInfos) {
        // Layers have been loaded, hide the loading icon add any new layers
        // to the store.
        dojo.style(dojo.byId("loading"), "display", "none");
        if (!layerInfos.hasOwnProperty("dynamicLayerInfos")) {
          var dynLayerInfos = map.getLayer("usa").createDynamicLayerInfosFromLayerInfos();
        } else {
          var dynLayerInfos = layerInfos.dynamicLayerInfos
        }
        dynLayerInfos.forEach( function (layerInfo) {
          if (!store.get(layerInfo.id)) {
            layerInfo.tocName = layerInfo.name.split(".").pop();
						layerInfo.icon    = layerInfo.tocName.toLowerCase();
            layerInfo.type    = "layerInfo";
            
            store.put( layerInfo, { parent: "layers"} );
          }
        },this);
      }

      function reorderLayers(item, insertIndex, before) {
        // Layer was dragged to a new location.

        function getLayers(parent, layers) {
          // Get all the children with type 'layerInfo' for the parent
          var children = store.getChildren(parent);
          var layers   = layers || [];

          children.forEach( function (child) {
            getLayers(child, layers);
          });
          if (parent.type == "layerInfo") {
            layers.push( parent );
          }
          return layers;
        }
  
        var layers = getLayers( store.get("layers") );            
        if (layers.length) {
          map.getLayer("usa").setDynamicLayerInfos(layers);
        }
      }

      function addLakes() {
        var dataSource, layerSource, drawingOptions, dynamicLayerInfo;
        var layerName = "ss6.gdb.Lakes";
        var options   = [];
        
        // show a loading icon and disable the "Add Lakes" button
        dojo.style(dojo.byId("loading"), "visibility", "visible");
        dijit.byId("lakes").set("disabled", true);

        // get existing layerInfos from the store.
        var dynLayerInfos = store.query( {type:"layerInfo"} );

        // create a table data source to access the lakes layer
        dataSource = new esri.layers.TableDataSource();
        dataSource.workspaceId = "MyDatabaseWorkspaceIDSSR2"; // not exposed via REST, sad face :(
        dataSource.dataSourceName = layerName;
        // and now a layer source
        layerSource = new esri.layers.LayerDataSource();
        layerSource.dataSource = dataSource;

        // create a new dynamic layer info object for the lakes layer
        dynamicLayerInfo        = new esri.layers.DynamicLayerInfo();
        dynamicLayerInfo.id     = dynLayerInfos.total;
        dynamicLayerInfo.name   = layerName;
        dynamicLayerInfo.source = layerSource;

        dynLayerInfos.push( dynamicLayerInfo );
        // set new infos, but don't refresh, map will be updated when the
        // drawing options are set
        map.getLayer("usa").setDynamicLayerInfos( dynLayerInfos, true);

        drawingOptions = new esri.layers.LayerDrawingOptions();
        drawingOptions.renderer = new esri.renderer.SimpleRenderer(
          new esri.symbol.SimpleFillSymbol(
            "solid",
            null,
            new dojo.Color([255, 0, 255, 0.75]) // fuschia lakes!
          )
        );
        options[4] = drawingOptions;

        map.getLayer("usa").setLayerDrawingOptions(options);
      }

      function init() {
        var urlBase = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer";
        var urlRef  = "http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer";
        var urlDyn  = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer";
        var popup   = Popup(null, dojo.create("div"));

        map = new esri.Map("map", { 
          center: [-86.636, 44.882],
          zoom: 6,
          infoWindow: popup,
          slider: false
        });

        var basemap  = new esri.layers.ArcGISTiledMapServiceLayer(urlBase);
        var refLayer = new esri.layers.ArcGISTiledMapServiceLayer(urlRef);
        var usaLayer = new esri.layers.ArcGISDynamicMapServiceLayer(urlDyn, { "id": "usa" });

				map.addLayers([basemap, refLayer, usaLayer]);

        // Create TOC store, model and tree.
        buildTOC("layerList");

        // build the layer list
        if ( usaLayer.loaded ) {
          storeLayers( map.getLayer("usa") );
        }
        // Establish event listeners.
        on (usaLayer, "updateEnd", function() {
          // Add any new layers to the TOC
          storeLayers( map.getLayer("usa") );
        });
        // add the lakes layer to the existing map service
        on (dijit.byId("lakes"), "click", addLakes);

        tree.on("checkBoxClick", layerClicked);
        model.on("pasteItem", reorderLayers );
      }
      // Let's get started when dojo is ready...
      ready (init);
    });
    </script>
  </head>

  <body class="tundra">
    <div data-dojo-type="dijit/layout/BorderContainer"
         data-dojo-props="design:'headline',gutters:false"
         style="width: 100%; height: 100%; margin: 0;">
      <div id="map"
           data-dojo-type="dijit/layout/ContentPane"
           data-dojo-props="region:'center'">

        <div id="feedback" class="shadow">
          <h3>Add and Re-order Layers</h3>
          <div id="info">
            <div id="note">
              Note:  This sample requires an ArcGIS Server version 10.1 map service to generate a renderer.
            </div>
            
            <p id="hint">
              Click and drag a map layer name below to re-order layers. The first layer in the list will be drawn on top.
            </p>

            <strong>Map Layers</strong>
            <img id="loading" src="http://dl.dropbox.com/u/2654618/loading_black.gif" />
            <br />
            <div id="layerList"></div>

            <button id="lakes" data-dojo-type="dijit.form.Button">Add Lakes</button>
            
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

